package edu.hawaii.senin.iclouds.simple;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import edu.hawaii.senin.iclouds.basics.ReadConfigException;

/**
 * This method incorporates simple cloud simulation scenario. It will load specified cloud config
 * and parse it. Next fixture will be generated and dumped into C:/snapshot.txt.
 *
 * @author Pavel Senin.
 *
 */
public class CloudSimulation {

  static Option help = new Option("help", "print this message");

  /**
   * Runs the simulation.
   *
   * @param args command line parameters.
   */
  @SuppressWarnings("static-access")
  public static void main(String[] args) {

    Option cfgFile = OptionBuilder.withArgName("file").hasArg().withDescription(
        "specifies config file to use").create("config");
    Option logFile = OptionBuilder.withArgName("file").hasArg().withDescription(
        "use given file for log").create("logfile");
    Option loggerType = OptionBuilder.withArgName("logtype").hasArg().withDescription(
        "logger format [ text, xml]").create("logtype");
    Option loggerFile = OptionBuilder.withArgName("file").hasArg().withDescription(
        "use given file for log").create("loggerfile");
    Option loggerLevel = OptionBuilder.withArgName("loglevel").hasArg().withDescription(
        "specifies the logger level [severe | fine | finer | finest]").create("loglevel");
    Option density = OptionBuilder.withArgName("value").hasArg().withDescription(
        "specifies the cloud density").create("density");
    Option accretionLimit = OptionBuilder.withArgName("value").hasArg().withDescription(
        "specifies the accretion events limit").create("acclimit");
    Option iterationsLimit = OptionBuilder.withArgName("value").hasArg().withDescription(
        "specifies the iterations limit").create("itrlimit");
    Option dhRatio = OptionBuilder.withArgName("value").hasArg().withDescription(
        "specifies the D/H ratio").create("dhratio");
    Option buryRoutine = OptionBuilder.withArgName("value").hasArg().withDescription(
        "specifies the D/H ratio").create("bury");
    Option cascadeRoutine = OptionBuilder.withArgName("value").hasArg().withDescription(
    "switches cascade (H release from OH+H2, OH+CO and OD+H2) on and off").create("cascade");

    Options options = new Options();

    options.addOption(help);
    options.addOption(cfgFile);
    options.addOption(logFile);
    options.addOption(loggerFile);
    options.addOption(loggerLevel);
    options.addOption(loggerType);
    options.addOption(density);
    options.addOption(accretionLimit);
    options.addOption(iterationsLimit);
    options.addOption(dhRatio);
    options.addOption(buryRoutine);
    options.addOption(cascadeRoutine);

    // create the parser
    CommandLineParser parser = new GnuParser();
    try {
      // parse the command line arguments
      CommandLine line = parser.parse(options, args);

      if (line.hasOption("help")) {
        // automatically generate the help statement
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("java -jar iclouds.jar ", options);
        System.exit(10);
      }

      Cloud model = new Cloud();

      CloudParametersMessage message = new CloudParametersMessage();

      if (line.hasOption("config")) {
        message.addParameter(CloudParametersMessage.CFGNAME, line.getOptionValue("config"));
      }

      if (line.hasOption("logfile")) {
        message.addParameter(CloudParametersMessage.LOGNAME, line.getOptionValue("logfile"));
      }

      if (line.hasOption("loggerfile")) {
        message.addParameter(CloudParametersMessage.LOGGERNAME, line.getOptionValue("loggerfile"));
      }

      if (line.hasOption("logtype")) {
        message.addParameter(CloudParametersMessage.LOGGERTYPE, line.getOptionValue("logtype"));
      }

      if (line.hasOption("loglevel")) {
        message.addParameter(CloudParametersMessage.LOGGERLEVEL, line.getOptionValue("loglevel"));
      }

      if (line.hasOption("density")) {
        message.addParameter(CloudParametersMessage.DENSITY, line.getOptionValue("density"));
      }

      if (line.hasOption("acclimit")) {
        message.addParameter(CloudParametersMessage.ACCSTEP, line.getOptionValue("acclimit"));
      }

      if (line.hasOption("itrlimit")) {
        message.addParameter(CloudParametersMessage.ITRLIMIT, line.getOptionValue("itrlimit"));
      }

      if (line.hasOption("dhratio")) {
        message.addParameter(CloudParametersMessage.DHRATIO, line.getOptionValue("dhratio"));
      }

      if (line.hasOption("bury")) {
        message.addParameter(CloudParametersMessage.BURY, line.getOptionValue("bury"));
      }

      if (line.hasOption("cascade")) {
        message.addParameter(CloudParametersMessage.CASCADE, line.getOptionValue("cascade"));
      }

      model.setParameters(message);

      // start the actual simulation
      if (model.modelReady()) {
        new Thread(model).start();
      }
      else {
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("java -jar iclouds.jar ", options);
        System.exit(10);
      }

    }
    catch (ReadConfigException e) {
      e.printStackTrace();
    }
    catch (ParseException exp) {
      // oops, something went wrong
      System.err.println("Parsing failed.  Reason: " + exp.getMessage());
    }
  }

}
